package nl.infodation.emr.pricingservice.controller;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;

import nl.infodation.emr.pricingservice.data.AppliesSelection;
import nl.infodation.emr.psrefdata.entity.Product;
import nl.infodation.emr.utility.StringUtil;

import com.vaadin.data.util.BeanItem;

@SuppressWarnings({"deprecation", "rawtypes"})
public class AppliesSelectionController extends AbstractBaseController<Object, AppliesSelection, Integer> {

	public AppliesSelectionController() {
		setEntityManagerFactoryForRole();
	}

	@Override
	public long getTotalNumberItemByCriteria(AppliesSelection t) {
		long countResult = 0l;
		setEntityManagerFactoryForRole();
		EntityManager entityManager = null;
		try {
			entityManager = EM_FACTORY.createEntityManager();
			entityManager.getTransaction().begin();
			queryString.setLength(0);
			final AppliesSelection a = (AppliesSelection) t;

			buildSelectCount(new Product());
			buildQueryForAppliesSelection(a);

			final TypedQuery<Long> query = entityManager.createQuery(queryString
					.toString(), Long.class);
			LOG.info("Executing the query \"{}\".", queryString);
			countResult = (Long) query.getSingleResult();
			;

			entityManager.getTransaction().commit();

		} catch (IllegalStateException ex) {
			LOG.error("Error reading getTotalNumberItemByCriteria", ex);
			if (entityManager != null
					&& entityManager.getTransaction().isActive()) {
				LOG.info("Rolling back...");
				entityManager.getTransaction().rollback();
			}
		} finally {
			if (entityManager != null && entityManager.isOpen()) {
				entityManager.close();
			}
		}
		return countResult;
	}

	@Override
	public List<BeanItem> getPaginationByCriteria(AppliesSelection object, int startPage,
			int pageSize) {
		final List<BeanItem> beans = new ArrayList<BeanItem>();
		setEntityManagerFactoryForRolePopup(object.getBussinesLine());
		EntityManager entityManager = null;
		try {
			entityManager = EM_FACTORY.createEntityManager();
			entityManager.getTransaction().begin();
			queryString.setLength(0);
			final AppliesSelection a = (AppliesSelection) object;

			buildSelect(new Product());
			buildQueryForAppliesSelection(a);

			final TypedQuery<Product> query = entityManager.createQuery(
					queryString.toString(), Product.class);
			if (startPage > 0) {
				query.setFirstResult((startPage - 1) * pageSize);
			} else {
				query.setFirstResult(1);
			}
			query.setMaxResults(pageSize);
			LOG.info("Executing the query \"{}\".", queryString);
			final List<Product> results = query.getResultList();
			if (!results.isEmpty()) {
				for (Product p : results) {
					AppliesSelection appliesSelection = new AppliesSelection();
					appliesSelection.setFamily(p.getFamily());
					appliesSelection.setSubFamily(p.getSubFamily());
					appliesSelection.setProductCode(p.getProductCode());
					appliesSelection.setLotId(String.valueOf(p.getLotId()));
					appliesSelection.setBrand(p.getBrand());
					appliesSelection
							.setCountryCode(p
									.getCommercialReferences()
									.getOffer()
									.getSalesSupport()
									.getCountryCode());
					appliesSelection.setProductId(String.valueOf(p.getProductId()));
					appliesSelection
							.setOfferId(String.valueOf(p
									.getCommercialReferences().getOffer()
									.getOfferId()));
					appliesSelection.setCategory(p.getCommercialReferences().getOffer().getCategory());
					
					beans.add(new BeanItem<AppliesSelection>(appliesSelection));
				}
			}

			entityManager.getTransaction().commit();

		} catch (IllegalStateException ex) {
			LOG.error("Error reading getPaginationByCriteria.", ex);
			if (entityManager != null
					&& entityManager.getTransaction().isActive()) {
				LOG.info("Rolling back...");
				entityManager.getTransaction().rollback();
			}
		} finally {
			if (entityManager != null && entityManager.isOpen()) {
				entityManager.close();
			}
		}
		return beans;
	}

	private void buildQueryForAppliesSelection(AppliesSelection a) {
		if (!queryString.toString().toLowerCase().contains("where")) {
			append(" WHERE ");
		}

		boolean mustAND = false;

		if (!StringUtil.isEmptyOrBlank(a.getProductCode())) {
			if (mustAND) {
				append(" AND ");
			}

			append(queryObjChar + "productCode" + " LIKE '%"
					+ a.getProductCode() + "%'");
			mustAND = true;
		}
		
		if (!StringUtil.isEmptyOrBlank(a.getProductId())) {
			try {
				long productId = Long.parseLong(a.getProductId());
				if (mustAND) {
					append(" AND ");
				}
				
				append(queryObjChar + "productId" + " LIKE '%" 
						+ productId + "%'");
				mustAND = true;

			} catch (NumberFormatException ex) {
				LOG.error("Error converting productId string type to long type: ",
						ex);
			}
		}
		
		if (!StringUtil.isEmptyOrBlank(a.getCountryCode())) {
			if (mustAND) {
				append(" AND ");
			}

			append(queryObjChar + "commercialReferences.offer.salesSupport.countryCode"
					+ " LIKE '%" + a.getCountryCode() + "%'");
			mustAND = true;
		} else {
			if (mustAND) {
				append(" AND ");
			}

			append(queryObjChar + "commercialReferences.offer.salesSupport.countryCode"
					+ " IS NOT NULL");
			mustAND = true;
		}
	}

	@Override
	public long getTotalNumberItem() {
		return getTotalNumberItemByCriteria(new AppliesSelection());
	}

	@Override
	protected Boolean isObject(Field field) {
		return Boolean.FALSE;
	}

	@Override
	protected Object buildCriteria(AppliesSelection search) {
		// no use
		return null;
	}

}
